package com.xxx.service.user.impl;

import com.xxx.common.constant.RedisConstant;
import com.xxx.common.enums.LoginType;
import com.xxx.common.enums.SmsType;
import com.xxx.common.model.RespEnum;
import com.xxx.exception.ServerException;
import com.xxx.model.user.req.ReqRefreshTokenVo;
import com.xxx.model.user.res.ResRefreshTokenVo;
import com.xxx.num.NumberUtil;
import com.xxx.para.ParametersUtil;
import com.xxx.redis.StringRedisUtil;
import com.xxx.service.user.UserCommonService;
import com.xxx.token.TokenUitl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.support.WebApplicationContextUtils;

/**
 * @author Flying
 * @Description
 * @date 13:29 2018-08-24
 **/

@Service
@Slf4j
public class UserCommonServiceImpl implements UserCommonService {

    @Autowired
    private StringRedisUtil redisUtil;


    @Value("${spring.profiles.active}")
    private String profile;

    /**
     * 刷新token
     *
     * @param reqRefreshTokenVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResRefreshTokenVo refreshToken(ReqRefreshTokenVo reqRefreshTokenVo) {
        String  userId = redisUtil.getString(RedisConstant.USER_REFRESH_TOKEN+ reqRefreshTokenVo.getRefreshToken());
        if(userId==null){
            throw new ServerException(RespEnum.LONG_TERM_USER_NOT_LOGGED_IN);
        }
        String token  = reqRefreshTokenVo.getRefreshToken();
        String splitChar = "_";
        String[] tokenPar = token.split(splitChar);
        Integer tokenMiniParameterCount = 2;
        if(tokenPar.length>= tokenMiniParameterCount ){
            try {
                LoginType loginType = LoginType.valueOf(tokenPar[1]);
                return this.createToken(userId,loginType);
            }catch (Exception e){
                throw new ServerException(RespEnum.LONG_TERM_USER_NOT_LOGGED_IN);
            }
        }
        return this.createToken(userId,LoginType.NAPP);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResRefreshTokenVo createToken(String userId, LoginType loginType){


        String accessTokenOld = redisUtil.getString(RedisConstant.USER_ACCESS_RECORD_TOKEN+loginType.name()+"_"+userId);
        String refreshTokenOld = redisUtil.getString(RedisConstant.USER_REFRESH_RECORD_TOKEN+loginType.name()+"_"+userId);
        if(refreshTokenOld != null){
            redisUtil.del(RedisConstant.USER_REFRESH_TOKEN+refreshTokenOld);
        }
        if(accessTokenOld != null){
            redisUtil.del(RedisConstant.USER_ACCESS_TOKEN+accessTokenOld);
        }
        redisUtil.del(RedisConstant.USER_ACCESS_RECORD_TOKEN+loginType.name()+"_"+userId);
        redisUtil.del(RedisConstant.USER_REFRESH_RECORD_TOKEN+loginType.name()+"_"+userId);

        ResRefreshTokenVo resRefreshTokenVo = new ResRefreshTokenVo();
        resRefreshTokenVo.setAccessToken(TokenUitl.getToken()+"_"+loginType.name());
        resRefreshTokenVo.setRefreshToken(TokenUitl.getToken()+"_"+loginType.name());

        redisUtil.set(RedisConstant.USER_ACCESS_RECORD_TOKEN+loginType.name()+"_"+userId, resRefreshTokenVo.getAccessToken(),60 * 60 * 24 * 7);
        redisUtil.set(RedisConstant.USER_ACCESS_TOKEN+ resRefreshTokenVo.getAccessToken(),userId ,60 * 60 * 24 * 7);

        redisUtil.set(RedisConstant.USER_REFRESH_RECORD_TOKEN+loginType.name()+"_"+userId, resRefreshTokenVo.getRefreshToken(),60 * 60 * 24 * 30);
        redisUtil.set(RedisConstant.USER_REFRESH_TOKEN+ resRefreshTokenVo.getRefreshToken(),userId,60 * 60 * 24 * 30);


        return resRefreshTokenVo;
    }






    @Override
    public Boolean checkSmsCode(String phone, String code , SmsType smsType){
        if(smsType == null){
            throw new ServerException(RespEnum.REQUEST_PARAM_ERROR);
        }
        if(!redisUtil.comparisonValueAndDelete(smsType.getKey()+phone,code)){
            throw  new ServerException(RespEnum.SMS_CODE_ERROR);
        }
        redisUtil.del(smsType.getKey()+phone);
        return true;
    }






    /**
     * @param key
     * @author: revelin
     * @Date: 上午10:59 18-4-13
     * @Description: 生成验证码
     **/
    private String createSmsCode(String key) {
        String code = redisUtil.getString(key);
        if (code == null) {
            code = NumberUtil.customNum(100000);
        }
        return code;
    }


    /**
     * @param tel 手机号
     * @author: revelin
     * @Date: 上午11:25 18-1-19
     * @Description:验证码次数校验
     **/
    private void validateCount(String tel) {
        Object obj = redisUtil.hget(RedisConstant.SMS_COUNT_GROUP, tel);
        Integer count = obj == null ? 0 : Integer.parseInt(obj.toString());
        if (count >= 1000) {
            throw new ServerException(RespEnum.SMS_SEND_OUT_NUMBER);
        }
    }

    /**
     * 验证发送短信 再次发送是否再限定范围后执行
     *
     * @param ksy
     * @author Flying
     * 2018年1月24日 上午10:32:56
     */
    private void validateSendTime(String ksy) {
        String obj = redisUtil.getString(ksy + RedisConstant.REPEAT_SEND_SMS_TIME);
        if (!ParametersUtil.isNull(obj)) {
            throw new ServerException(RespEnum.REPEAT_SEND_SMS_TIME);
        }
    }

}
